/* 
 * FLAC 1.2.1 bitreader.c
 * implementation for NDS
 */

#ifndef _AUDIOREADER_H_
#define _AUDIOREADER_H_

#include <nds.h>

#include <cstdlib>
#include <stdint.h>
#include <string>
#include <cstdio>

#define AUDIOBUFFERSIZE 4096

class AudioReader
{
private:
	uint32_t buffer[AUDIOBUFFERSIZE];
	uint32_t capacity;
	uint32_t words;
	uint32_t bytes;
	uint32_t consumed_words;
	uint32_t consumed_bits;
	/* not used now
	 * reminder: swiCRC16() 
	uint32_t read_crc16;
	uint32_t crc16_align; */
	FILE *file;

	static const uint8_t byte_to_unary_table[256];
	static inline uint32_t count_zero_msbs(uint32_t word);
	static inline void swap_be_word(uint32_t *start);
	static inline void swap_be_block(uint32_t *start, uint32_t len);
	
	inline bool refill_buffer();
	inline uint32_t bits_left_for_byte_alignment();
	inline uint32_t get_input_bits_unconsumed();

public:
	bool init(std::string filename);
	bool clear();
	bool seek(long pos);
	long tell();
	bool eof();

	bool read_uint32_be(uint32_t *val, uint32_t bits);
	bool read_int32_be(int32_t *val, uint32_t bits);
	bool read_uint64_be(uint64_t *val, uint32_t bits);
	bool read_uint32_le(uint32_t *val, uint32_t bits);

	bool read_byte_block(uint8_t *val, uint32_t nvals, bool align);
	bool read_unary_unsigned(uint32_t *val);

	bool read_utf8_uint32(uint32_t *val, uint8_t *raw, uint32_t *rawlen);
	bool read_utf8_uint64(uint64_t *val, uint8_t *raw, uint32_t *rawlen);

	bool skip_bits(uint32_t bits);
	bool skip_byte_block(uint32_t nvals, bool align);

	/* FLAC */
	bool read_rice_signed(int32_t *val, uint32_t parameter);
	bool read_rice_signed_block(int32_t *vals, uint32_t nvals, uint32_t parameter);
};

#endif /* _AUDIOREADER_H_ */
